package com.sinping.qh.service.app.records.impl;


import com.google.common.collect.Lists;
import com.sinping.qh.api.exception.HandlerException;
import com.sinping.qh.api.support.ConstEum;
import com.sinping.qh.api.support.FrontPage;
import com.sinping.qh.api.support.ResDtoUtil;
import com.sinping.qh.domain.common.UploadImage;
import com.sinping.qh.domain.lab.LaboratoryDomain;
import com.sinping.qh.domain.records.*;
import com.sinping.qh.domain.user.UserInfo;
import com.sinping.qh.dto.admin.lab.InspectItemHiddenDangerDto;
import com.sinping.qh.dto.app.records.*;
import com.sinping.qh.dto.common.CommonDTO;
import com.sinping.qh.dto.common.ICommonDTO;
import com.sinping.qh.query.plan.CheckPlanByAppQuery;
import com.sinping.qh.query.records.CheckRecordByAppQuery;
import com.sinping.qh.query.records.CheckRecoredsQuery;
import com.sinping.qh.repository.mongo.lab.LaboratoryRepository;
import com.sinping.qh.repository.mongo.records.CheckRecordsRepository;
import com.sinping.qh.repository.mongo.records.HiddenDangerRecordRepository;
import com.sinping.qh.repository.mongo.records.HighLightRepository;
import com.sinping.qh.repository.mongo.user.UserInfoRepository;
import com.sinping.qh.repository.mongo.records.CheckPlanRepository;
import com.sinping.qh.service.MongoManager;
import com.sinping.qh.service.app.lab.impl.LaboratoryByAppServiceImpl;
import com.sinping.qh.service.app.records.ICheckPlanService;
import com.sinping.qh.service.common.CommonDbConst;
import com.sinping.qh.utils.mapper.BeanMapper;
import com.sinping.qh.utils.misc.IdGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.sql.Array;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * @author zhangjin
 * @create 2018/5/29
 */
@Service
public class CheckPlanServiceImpl implements ICheckPlanService {


    @Autowired
    CheckPlanRepository checkPlanRepository;

    @Autowired
    CheckRecordsRepository checkRecordsRepository;


    @Autowired
    UserInfoRepository userInfoRepository;

    /**
     * 实验室表
     */
    @Autowired
    LaboratoryRepository laboratoryRepository;

    @Autowired
    HighLightRepository highLightRepository;

    @Autowired
    LaboratoryByAppServiceImpl laboratoryByAppService;

    @Autowired
    MongoManager mongoManager;

    @Autowired
    HiddenDangerRecordRepository hiddenDangerRecordRepository;

    @Value(value = "${qh.upload.urlPath}")
    private String urlPath;

    /**
     * 一、检查院系和楼宇以及当前用户三个条件，如果有检查中和待审核的检查记录则提示信息
     * 二、
     *
     * @param checkPlanByAppDTO
     * @param commonDTO
     * @return
     */
    @Override
    public String preValidCheck(CheckPlanByAppDTO checkPlanByAppDTO, ICommonDTO commonDTO) {

        CheckPlan checkPlan = BeanMapper.map(checkPlanByAppDTO, CheckPlan.class);

        CheckRecoredsQuery checkRecoredsQuery = new CheckRecoredsQuery();

        checkRecoredsQuery.setCheckBuildingId(checkPlan.getCheckBuildingId());
        checkRecoredsQuery.setCheckUnitId(checkPlan.getCheckUnitId());
        checkRecoredsQuery.setCheckStatus("[12]");
        checkRecoredsQuery.setCheckUserId(((CommonDTO) commonDTO).getUserSessionDTO().getUserInfo().getId());

        List<CheckRecord> checkRecordList = mongoManager.find(checkRecoredsQuery, CheckRecord.class);
        ArrayList checkIds = Lists.newArrayList();
//        List<CheckRecordByAppDTO> checkRecordByAppDTOList=BeanMapper.mapList(checkRecordList,CheckRecordByAppDTO.class);
        for (CheckRecord checkRecord : checkRecordList) {
            checkIds.add(checkRecord.getId());
        }

        List<CheckRecord> newCheckRecordList =
                checkRecordsRepository.findCheckRecordsByIdInOrderByGmtCreatedDesc(checkIds);
        if (newCheckRecordList.size() > 0) {
            return newCheckRecordList.get(0).getCheckPlanId();
        } else {
            return "";
        }

    }

    /**
     * 一、新建检查计划 要去添加检查记录,检查记录初始化时检查人员和院系参加人员为空
     * 二、如果楼宇下面没有实验室则不能创建检查计划
     *
     * @param checkPlanByAppDTO
     */
    public CheckPlanByAppDTO save(CheckPlanByAppDTO checkPlanByAppDTO, ICommonDTO commonDTO) {

        //生成检查计划
        CheckPlan checkPlan = BeanMapper.map(checkPlanByAppDTO, CheckPlan.class);
        //新建检查时必须有当前用户
        List<CheckUser> users = getCheckUser(checkPlanByAppDTO);
        boolean isCurrentUser = false;
        for (CheckUser checkUser : users) {
            if (checkUser.getId().equals(((CommonDTO) commonDTO).getUserSessionDTO().getUserInfo().getId())) {
                isCurrentUser = true;
            }
        }
        if (!isCurrentUser) {
            throw new HandlerException(ConstEum.FAIL, "检查人员必须有当前用户");
        }
        //判断检查实验室和楼宇下面有没有实验室,如果没有实验室,则创建失败
        List<LaboratoryDomain> laboratoryDomains =
                laboratoryRepository.findLaboratoryDomainByUnitIdAndBuildingIdAndStatus(checkPlan.getCheckUnitId().toString(),
                        checkPlan.getCheckBuildingId().toString(), CommonDbConst.DB_DELETE_NORMAL);
        if (laboratoryDomains.size() == 0) {
            throw new HandlerException(ConstEum.FAIL, "当前楼宇下面没有实验室");
        }


        checkPlan.setId(IdGenerator.uuid2().toString());
        checkPlan.setCheckUser(users);

//        checkPlan.setStatus(CommonDbConst.DB_DELETE_NORMAL);
        checkPlan.setGmtCreated(new Date());
        checkPlan.setGmtModified(new Date());

        checkPlan = checkPlanRepository.save(checkPlan);


        //查询检查计划下的选择的院系和楼宇下的所有的实验室,检查人员和院系参加人员为空,因为可能会变

//        List<LaboratoryDomain> laboratoryDomains=
//                laboratoryRepository.findLaboratoryDomainByUnitIdAndBuildingIdAndStatus(checkPlan.getCheckUnitId().toString(),
//                checkPlan.getCheckBuildingId().toString(),CommonDbConst.DB_DELETE_NORMAL);

        //然后去创建检查记录
        //创建综合检查
        CheckRecord checkRecord = new CheckRecord();
        checkRecord.setId(IdGenerator.uuid2().toString());

        //检查计划id
        checkRecord.setCheckPlanId(checkPlan.getId());
        //检查类型
        checkRecord.setCheckType(CommonDbConst.CHECKRECORD_TYPE_ALL);

        //检查单位
        checkRecord.setCheckUnit(checkPlan.getCheckUnit());
        //检查单位id
        checkRecord.setCheckUnitId(checkPlan.getCheckUnitId());
        //检查楼宇
        checkRecord.setCheckBuilding(checkPlan.getCheckBuilding());
        //检查楼宇id
        checkRecord.setCheckBuildingId(checkPlan.getCheckBuildingId());
        //院系参加人员
        checkRecord.setUnionUnitUser("");
        //检查状态
        checkRecord.setCheckStatus(CommonDbConst.CHECKRECORD_STATUS_UNCHECK);
        //检查人
        checkRecord.setCheckUser(Lists.newArrayList());

        checkRecord.setGmtCreated(new Date());
        checkRecord.setGmtModified(new Date());

        checkRecordsRepository.save(checkRecord);

        //创建实验室检查记录,检查人员和院系参加人员为空,因为可能会变
        for (LaboratoryDomain laboratoryDomain : laboratoryDomains) {

            checkRecord = new CheckRecord();

            checkRecord.setId(IdGenerator.uuid2().toString());

            //检查计划id
            checkRecord.setCheckPlanId(checkPlan.getId());
            //检查类型
            checkRecord.setCheckType(CommonDbConst.CHECKRECORD_TYPE_LAB);

            //检查单位
            checkRecord.setCheckUnit(checkPlan.getCheckUnit());
            //检查单位id
            checkRecord.setCheckUnitId(checkPlan.getCheckUnitId());
            //检查楼宇
            checkRecord.setCheckBuilding(checkPlan.getCheckBuilding());
            //检查楼宇id
            checkRecord.setCheckBuildingId(checkPlan.getCheckBuildingId());
            //检查实验室名称
            checkRecord.setCheckLab(laboratoryDomain.getLabName());
            //检查实验室id
            checkRecord.setCheckLabId(laboratoryDomain.getId());
            //房间号
            checkRecord.setCheckRoom(laboratoryDomain.getRoomNo());
            //所属所室
            checkRecord.setOffices(laboratoryDomain.getOffices());
            //院系参加人员
            checkRecord.setUnionUnitUser("");
            //检查状态
            checkRecord.setCheckStatus(CommonDbConst.CHECKRECORD_STATUS_UNCHECK);
            //检查人
            checkRecord.setCheckUser(Lists.newArrayList());

            checkRecord.setGmtCreated(new Date());
            checkRecord.setGmtModified(new Date());

            checkRecordsRepository.save(checkRecord);
        }

        checkPlanByAppDTO = BeanMapper.map(checkPlan, CheckPlanByAppDTO.class);
        return checkPlanByAppDTO;


    }

    public FrontPage findPage(FrontPage frontPage, ICommonDTO commonDTO) {
        Sort sort;
        if (StringUtils.isNotBlank(frontPage.getProp()) &&
                StringUtils.isNotBlank(frontPage.getOrder())) {
            sort = new Sort(Sort.Direction.fromString(frontPage.getOrder()), frontPage.getProp());

        } else {
            sort = new Sort(Sort.Direction.DESC, "gmt_created");
        }
        //查询条件
        CheckPlanByAppQuery checkPlanQuery = new CheckPlanByAppQuery();
        UserInfo userInfo = BeanMapper.map(((CommonDTO) commonDTO).getUserSessionDTO().getUserInfo(), UserInfo.class);
        checkPlanQuery.setCheckUserId(userInfo.getId());
        PageRequest page = new PageRequest(frontPage.getPage() - 1, frontPage.getSize(), sort);

        Page<CheckPlan> checkPlans = mongoManager.findPage(checkPlanQuery, page, CheckPlan.class);

        ResDtoUtil.defaultUtil().pageDomainDtoToFrontDto(checkPlans, CheckPlanByAppDTO.class, frontPage);
        return frontPage;
    }

    public CheckPlanByAppDTO findOne(String id) {
        CheckPlan checkPlan = checkPlanRepository.findOne(id);
        CheckPlanByAppDTO checkPlanByAppDTO = BeanMapper.map(checkPlan, CheckPlanByAppDTO.class);
        return checkPlanByAppDTO;
    }

    /**
     * 删除检查计划：条件： 下面所有的检查记录的检查状态为未检查
     * 删除时将会物理删除下面所有的检查记录
     *
     * @param id
     * @return
     */
    @Override
    public boolean delete(String id) {
        CheckPlan checkPlan = checkPlanRepository.findOne(id);

        if (checkPlan == null) {
            throw new HandlerException(ConstEum.FAIL, "没有找到检查计划");
        }

        List<CheckRecord> checkRecords = checkRecordsRepository.findCheckRecordsByCheckPlanId(id);
        //没有检查记录才删除

        for (CheckRecord checkRecord : checkRecords) {

            if (!checkRecord.getCheckStatus().equals(CommonDbConst.CHECKRECORD_STATUS_UNCHECK)) {
                throw new HandlerException(ConstEum.FAIL, "已经存在开始的检查记录");
            }

        }
//        checkPlan.setStatus(CommonDbConst.DB_DELETE_LOGICAL);
        checkPlanRepository.delete(id);
        //删除检查计划下的检查记录
        for (CheckRecord checkRecord : checkRecords) {
            checkRecordsRepository.delete(checkRecord.getId());
        }


        return true;
    }

    @Override
    public CheckPlanByAppDTO update(CheckPlanByAppDTO checkPlanByAppDTO, ICommonDTO commonDTO) {

        CheckPlan checkPlan = checkPlanRepository.findOne(checkPlanByAppDTO.getId());
        if (checkPlan == null) {
            throw new HandlerException(ConstEum.FAIL, "没有找到检查计划");
        }
        //院系参加人员
//        if(StringUtils.isNotBlank(checkPlanByAppDTO.getUnionUnitUser())) {
        checkPlan.setUnionUnitUser(checkPlanByAppDTO.getUnionUnitUser());
//        }

        //检查人员
        if (checkPlanByAppDTO.getCheckUserId().size() > 0) {
            if (checkPlan.getCreateUserId().equals(((CommonDTO) commonDTO).getUserSessionDTO().getUserInfo().getId())) {
                checkPlan.setCheckUser(getCheckUser(checkPlanByAppDTO));
            } else {
//                throw new HandlerException(ConstEum.FAIL,"只能创建人可以修改检查人员");
            }
        } else {
            throw new HandlerException(ConstEum.FAIL, "检查人员不能为空");
        }

        checkPlan.setGmtModified(new Date());
        checkPlan = checkPlanRepository.save(checkPlan);

        checkPlanByAppDTO = BeanMapper.map(checkPlan, CheckPlanByAppDTO.class);

        return checkPlanByAppDTO;
    }

    /**
     * 根据检查人员id,获取检查人员详情
     *
     * @param checkPlanByAppDTO
     * @return
     */
    private ArrayList<CheckUser> getCheckUser(CheckPlanByAppDTO checkPlanByAppDTO) {
        ArrayList<CheckUser> checkUsers = new ArrayList<CheckUser>();
        for (String id : checkPlanByAppDTO.getCheckUserId()) {
            UserInfo userInfo = userInfoRepository.findOne(id.toString());
            if (userInfo != null) {
                CheckUser checkUser = BeanMapper.map(userInfo, CheckUser.class);
                checkUsers.add(checkUser);
            }
        }
        return checkUsers;
    }

    public CheckPlanByAppDTO findPlanOffLine(String planid,ICommonDTO commonDTO) {
        Sort sort = new Sort(Sort.Direction.DESC, "gmt_created");
        //查询条件
        CheckPlanByAppQuery checkPlanQuery = new CheckPlanByAppQuery();
        UserInfo userInfo = BeanMapper.map(((CommonDTO) commonDTO).getUserSessionDTO().getUserInfo(), UserInfo.class);
        checkPlanQuery.setCheckUserId(userInfo.getId());
        //检查计划id
        checkPlanQuery.setCheckPlanId(planid);

        //检查计划
        List<CheckPlan> checkPlanList = mongoManager.find(checkPlanQuery, CheckPlan.class, sort);

        List<CheckPlanByAppDTO> planAppDTOList = BeanMapper.mapList(checkPlanList, CheckPlanByAppDTO.class);

        List<String> checkStatusList=new ArrayList<>();
        //存储所有的图片路径
        ArrayList<String> imageList=new ArrayList<>();
        //0 未检查 1 检查中
        checkStatusList.add(CommonDbConst.CHECKRECORD_STATUS_UNCHECK);
        checkStatusList.add(CommonDbConst.CHECKRECORD_STATUS_CHECKING);
        if (null != planAppDTOList && planAppDTOList.size() > 0) {

            for (CheckPlanByAppDTO planDto : planAppDTOList) {
                //检查记录
                CheckRecordByAppQuery checkRecordByAppQuery = new CheckRecordByAppQuery();
                checkRecordByAppQuery.setCheckStatus(checkStatusList);
                checkRecordByAppQuery.setCheckPlanId(planDto.getId());

                List<CheckRecord> checkRecordList = mongoManager.find(checkRecordByAppQuery, CheckRecord.class);
                //List<CheckRecord> checkRecordList = checkRecordsRepository.findCheckRecordsByCheckPlanIdAndCheckStatusOrderByGmtCreatedDesc(planDto.getId(), "1");
                List<CheckRecordOffLineByAppDTO> checkRecordByAppDTOS = BeanMapper.mapList(checkRecordList, CheckRecordOffLineByAppDTO.class);

                for (CheckRecordOffLineByAppDTO checkRecordOffLineByAppDTO : checkRecordByAppDTOS) {
                    //亮点记录(只有一条)
                    HighLightRecord highLightRecord =
                            highLightRepository.findHighLightRecordByCheckId(checkRecordOffLineByAppDTO.getId());
                    if(highLightRecord!=null) {
                        if(highLightRecord!=null && highLightRecord.getUploadImageList().size()>0)
                        {
                            List<UploadImage> uploadImageDTOList=
                                    highLightRecord.getUploadImageList();

                            for (int i=0;i<uploadImageDTOList.size();i++)
                            {
                                uploadImageDTOList.get(i).setPath(urlPath+uploadImageDTOList.get(i).getPath());
                                imageList.add(uploadImageDTOList.get(i).getPath());
                            }
                        }
                        HighLightByAppDTO highLightByAppDTO = BeanMapper.map(highLightRecord, HighLightByAppDTO.class);
                        checkRecordOffLineByAppDTO.setItems(highLightByAppDTO);
                    }

                    //0 综合检查记录 1 实验室检查记录 的检查记录
                    List<InspectItemHiddenDangerDto> inspectItemHiddenDangerDto =
                            laboratoryByAppService.getListData(checkRecordOffLineByAppDTO.getCheckType(), checkRecordOffLineByAppDTO.getCheckLabId());
                    checkRecordOffLineByAppDTO.setInspectItemHiddenDangerList(inspectItemHiddenDangerDto);

                    //存储隐患记录
                    List<HiddendangerRecord> hiddendangerRecords=
                            hiddenDangerRecordRepository.findAllByCheckId(checkRecordOffLineByAppDTO.getId());

                    for (HiddendangerRecord hiddendangerRecord:hiddendangerRecords)
                    {
                        hiddendangerRecord.setOffline("0");
                        hiddenDangerRecordRepository.save(hiddendangerRecord);
                        //给图片设置路径
                        if(hiddendangerRecord!=null && hiddendangerRecord.getUploadImageList().size()>0)
                        {
                            List<UploadImage> uploadImageDTOList=
                                    hiddendangerRecord.getUploadImageList();

                            for (int i=0;i<uploadImageDTOList.size();i++)
                            {
                                uploadImageDTOList.get(i).setPath(urlPath+uploadImageDTOList.get(i).getPath());
                                imageList.add(uploadImageDTOList.get(i).getPath());
                            }
                        }

                    }

                    List<HiddendangerByAppDTO> hiddendangerByAppDTOS
                            =BeanMapper.mapList(hiddendangerRecords,HiddendangerByAppDTO.class);

                    checkRecordOffLineByAppDTO.setHiddendangerByAppDTOS(hiddendangerByAppDTOS);


                }
                planDto.setCheckRecords(checkRecordByAppDTOS);
            }

        }
        CheckPlanByAppDTO checkPlanByAppDTO=new CheckPlanByAppDTO();
        if(planAppDTOList.size()>0) {
            checkPlanByAppDTO = planAppDTOList.get(0);
            checkPlanByAppDTO.setImageList(imageList);
        }else{
            throw new HandlerException(ConstEum.FAIL,"找不到检查计划");
        }
        return checkPlanByAppDTO;
    }
}
